package com.yonyou.pmclouds.workquality.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertMultiProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.consts.EnableStatusConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.industryandtype.entity.TypeDocVO;
import com.yonyou.pmclouds.industryandtype.mapper.TypeDocMapper;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.workquality.entity.WorkqualityDetailVO;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityDetailMapper;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityMapper;
import com.yonyou.pmclouds.workquality.process.*;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = WorkqualityService.class)
public class WorkqualityServiceImpl implements WorkqualityService {

    @Autowired
    private WorkqualityMapper mapper;

    @Autowired
    private WorkqualityDetailMapper detailMapper;

    @Autowired
    public WorkqualityQueryService queryService;

    @Autowired
    private TypeDocMapper typeDocMapper;

    @Autowired
    private PictureRemoteService pictureRemoteService;


    @Override
    public WorkqualityVO insert(WorkqualityVO workqualityVO) throws BusinessException {

        SingleInsertBpTemplate<WorkqualityVO> bp = new SingleInsertBpTemplate<>(mapper);
        SingleInsertBpTemplate<WorkqualityDetailVO> bpdetail = new SingleInsertBpTemplate<>(detailMapper);
        // TODO: 2019/9/23 巡查内容
        bp.addBeforeProcessor(new WorkqualityInsertCheckProcessor(mapper)).addBeforeProcessor(new AuditInfoInsertProcessor<WorkqualityVO>());
        bpdetail.addBeforeProcessor(new AuditInfoInsertProcessor<WorkqualityDetailVO>());

        bp.insert(workqualityVO);
        if (workqualityVO.getItemtabledata() != null && workqualityVO.getItemtabledata().length > 0) {
            for (WorkqualityDetailVO detail : workqualityVO.getItemtabledata()) {
                detail.setPkWorkquality(workqualityVO.getPkWorkquality());
                detail.setEnableStatus(EnableStatusConst.ENABLE);
                bpdetail.insert(detail);
            }
            // 插入示例图片
            this.insertExamplePics(workqualityVO);
        }
        //插入完成后返回一个列表态

        return queryService.queryByID(workqualityVO.getPkWorkquality());
    }

    @Override
    public WorkqualityVO update(WorkqualityVO workqualityVO) throws BusinessException {

        SingleUpdateBpTemplate<WorkqualityVO> bp = new SingleUpdateBpTemplate<>(mapper, new String[]{"checkname", "checktype", "pkProcedure"});
        SingleUpdateBpTemplate<WorkqualityDetailVO> bpdetail = new SingleUpdateBpTemplate<>(detailMapper, new String[]{"checkitem", "checkdescription", "needphoto", "needmeasurement", "checkcode"});
        SingleDeleteBpTemplate<WorkqualityDetailVO> deleteBpTemplate = new SingleDeleteBpTemplate<>(detailMapper);
        SingleInsertBpTemplate<WorkqualityDetailVO> insertBpTemplate = new SingleInsertBpTemplate<>(detailMapper);

        bp.addBeforeProcessor(new WorkqualityUpdateCheckProcessor(mapper));
        bp.update(workqualityVO);

        insertBpTemplate.addBeforeProcessor(new AuditInfoInsertProcessor<WorkqualityDetailVO>());
        bpdetail.addBeforeProcessor(new AuditInfoUpdateProcessor<WorkqualityDetailVO>());
        deleteBpTemplate.addBeforeProcessor(new AuditInfoUpdateProcessor<WorkqualityDetailVO>());

        if (workqualityVO.getItemtabledata() != null && workqualityVO.getItemtabledata().length > 0) {
            for (WorkqualityDetailVO detail : workqualityVO.getItemtabledata()) {
                if (detail.getPkWorkqualitydetail() != null && !detail.getPkWorkqualitydetail().equals("")) {
                    bpdetail.update(detail);
                } else if (detail.getPkWorkqualitydetail() == null || detail.getPkWorkqualitydetail().equals("")) {
                    detail.setPkWorkquality(workqualityVO.getPkWorkquality());
                    insertBpTemplate.insert(detail);
                }
            }

            // 查询更新前所有的检查项
            List<WorkqualityDetailVO> originDetailVos = detailMapper.queryByWorkqualityId(workqualityVO.getPkWorkquality());
            // 删除数据库存在但界面没有的检查项
            List<WorkqualityDetailVO> delList = getDeleteDetailVos(originDetailVos, workqualityVO.getItemtabledata());
            if (delList != null && delList.size() > 0) {
                for (WorkqualityDetailVO vo : delList) {
                    deleteBpTemplate.delete(vo);
                }
            }
            // 更新示例照片
            updateExamplePics(workqualityVO);
        }

        return queryService.queryByID(workqualityVO.getPkWorkquality());
    }

    /**
     * 获得本次要删除的检查项
     *
     * @param originDetailVos
     * @param vos
     * @return
     */
    private List<WorkqualityDetailVO> getDeleteDetailVos(List<WorkqualityDetailVO> originDetailVos, WorkqualityDetailVO[] vos) {
        List<WorkqualityDetailVO> results = new ArrayList<>();
        if (originDetailVos == null || originDetailVos.size() == 0)
            return results;
        Map<String, WorkqualityDetailVO> pkToVo = new HashMap<>();
        if (ArrayUtils.isNotEmpty(vos)) {
            for (WorkqualityDetailVO vo : vos) {
                pkToVo.put(vo.getPkWorkqualitydetail(), vo);
            }
        }
        for (WorkqualityDetailVO originVo : originDetailVos) {
            if (!pkToVo.containsKey(originVo.getPkWorkqualitydetail()))
                results.add(originVo);
        }

        return results;
    }

    /**
     * 更新示例图片
     *
     * @param workqualityVO
     */
    private void updateExamplePics(WorkqualityVO workqualityVO) throws BusinessException {
        if (workqualityVO == null || ArrayUtils.isEmpty(workqualityVO.getItemtabledata()))
            return;
        List<PictureVO> picList = setExamplePicInfo(workqualityVO);
        // 更新图片
        pictureRemoteService.updateExamplePics(picList.toArray(new PictureVO[picList.size()]), workqualityVO.getPkWorkquality());
    }

    /**
     * 设置示例图片信息
     *
     * @param workqualityVO
     * @return
     */
    private List<PictureVO> setExamplePicInfo(WorkqualityVO workqualityVO) throws BusinessException {
        List<PictureVO> picList = new ArrayList<>();
        for (WorkqualityDetailVO detailVO : workqualityVO.getItemtabledata()) {
            // 示例图片为空
            if (ArrayUtils.isEmpty(detailVO.getExamplePictures()))
                continue;
            if (detailVO.getExamplePictures().length > 5)
                throw new BusinessException("每个检查项下的示例照片不能超过五张");
            int i = 1;
            for (PictureVO pic : detailVO.getExamplePictures()) {
                pic.setSequence(i);
                i++;
                pic.setExampleFlag(1);
                pic.setPk_entity(detailVO.getPkWorkqualitydetail());
                pic.setPk_bill(workqualityVO.getPkWorkquality());
                picList.add(pic);
            }
        }

        return picList;
    }

    @Override
    public void delete(WorkqualityVO workqualityVO) throws BusinessException {
        SingleDeleteBpTemplate<WorkqualityVO> bp = new SingleDeleteBpTemplate<>(mapper);
        bp.addBeforeProcessor(new WorkqualityDeleteCheckProcessor(mapper));
        bp.delete(workqualityVO);
        // 删除所有示例照片
        pictureRemoteService.deleteExamplePicsOfBill(workqualityVO.getPkWorkquality());
    }

    //===========================分界线=======================================================================

    /**
     * 预览质量标准预置模板
     * @param pkType
     * @return
     * @throws BusinessException
     */
    @Override
    public WorkqualityVO[] getPreviewWorkqualitys(String pkType) throws BusinessException {
        if (StringUtils.isEmpty(pkType)) {
            return new WorkqualityVO[0];
        }
        List<WorkqualityVO> resultList = getWorkqualityWithDetail(new String[]{pkType});
        return resultList == null ? new WorkqualityVO[0] : resultList.toArray(new WorkqualityVO[0]);
    }

    /**
     * 用户导入质量标准预置模板
     * @param workqualityList
     * @return
     * @throws BusinessException
     */
    @Override
    public String[] insertPresetWorkqualitys(List<WorkqualityVO> workqualityList) throws BusinessException {
        if(workqualityList == null || workqualityList.size() == 0){
            return new String[0];
        }
        return insertMulti(workqualityList.toArray(new WorkqualityVO[0]));
    }

    //首页的启用
    @Override
    public WorkqualityVO enable(WorkqualityVO workqualityVO) throws BusinessException {
        SingleUpdateBpTemplate<WorkqualityVO> bp = new SingleUpdateBpTemplate<>(mapper, new String[]{EnableStatusConst.ENABLE_STATUS});
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<WorkqualityVO>());
        workqualityVO.setEnableStatus(EnableStatusConst.ENABLE);

        return bp.update(workqualityVO);
    }

    //首页的停用
    @Override
    public WorkqualityVO disable(WorkqualityVO workqualityVO) throws BusinessException {
        SingleUpdateBpTemplate<WorkqualityVO> bp = new SingleUpdateBpTemplate<>(mapper, new String[]{EnableStatusConst.ENABLE_STATUS});
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<WorkqualityVO>());
        workqualityVO.setEnableStatus(EnableStatusConst.DISABLE);

        return bp.update(workqualityVO);
    }

    @Override
    public WorkqualityVO insertExamplePics(WorkqualityVO workqualityVO) throws BusinessException {
        if (workqualityVO == null || ArrayUtils.isEmpty(workqualityVO.getItemtabledata()))
            return workqualityVO;
        List<PictureVO> insertPics = setExamplePicInfo(workqualityVO);

        if (insertPics.size() > 0)
            pictureRemoteService.insertPictures(insertPics.toArray(new PictureVO[insertPics.size()]));

        return workqualityVO;
    }

    /**
     * 根据类型主键，查询质量标准，设置租户，并添加对应的检查项
     * @param pkTypes
     * @return
     * @throws BusinessException
     */
    private List<WorkqualityVO> getWorkqualityWithDetail(String[] pkTypes) throws BusinessException {
        if (ArrayUtils.isEmpty(pkTypes)) {
            return new ArrayList<WorkqualityVO>();
        }
        //查询关联类型和质量标准的类型档案实体
        TypeDocVO[] typeDocVOS = typeDocMapper.getByIds(pkTypes);
        if (ArrayUtils.isEmpty(typeDocVOS)) {
            return new ArrayList<WorkqualityVO>();
        }
        //得到所有的质量标准的主键
        String[] pkWorkqualitys = new String[typeDocVOS.length];
        for (int i = 0; i < typeDocVOS.length; i++) {
            if (typeDocVOS[i] != null) {
                pkWorkqualitys[i] = typeDocVOS[i].getPkDoc();
            }
        }

        List<WorkqualityVO> workqualityList = mapper.queryByIds(SqlUtil.getSqlIn(pkWorkqualitys));
        List<WorkqualityDetailVO> detailList = detailMapper.queryByWorkqualityIds(SqlUtil.getSqlIn(pkWorkqualitys));
        if(workqualityList != null){
            for(WorkqualityVO vo : workqualityList){
                if(vo != null){
                    vo.setPkTenant(RuntimeEnvironment.getTenantId());  //设置租户
                }
            }
        }
        if(workqualityList == null || workqualityList.size() == 0 || detailList == null || detailList.size() == 0){
            return workqualityList;
        }
        Map<String, List<WorkqualityDetailVO> > recordMap = new HashMap<>();  //记录质量标准主键对应的检查项
        for(WorkqualityDetailVO detailVO : detailList){
            if(detailVO == null) continue;
            if(recordMap.get(detailVO.getPkWorkquality()) == null){
                recordMap.put(detailVO.getPkWorkquality(), new ArrayList<WorkqualityDetailVO>());
            }
            recordMap.get(detailVO.getPkWorkquality()).add(detailVO);
        }
        for(WorkqualityVO vo : workqualityList) {
            if(vo != null && recordMap.get(vo.getPkWorkquality()) != null){
                //添加质量标准对应的检查项
                vo.setItemtabledata(recordMap.get(vo.getPkWorkquality()).toArray(new WorkqualityDetailVO[0]));
            }
        }
        return workqualityList;
    }



    /**
     * 批量插入质量标准，仅供用户导入质量标准预置模板接口使用
     * @param workqualityVOS
     * @return
     * @throws BusinessException
     */
    private String[] insertMulti(WorkqualityVO[] workqualityVOS) throws BusinessException {

        if(workqualityVOS == null) return new String[0];
        List<String> resultList = new ArrayList<>();
        MultiInsertBpTemplate<WorkqualityVO> bp = new MultiInsertBpTemplate<>(mapper);
        MultiInsertBpTemplate<WorkqualityDetailVO> bpDetail = new MultiInsertBpTemplate<>(detailMapper);

        bp.addBeforeProcessor(new AuditInfoInsertMultiProcessor<WorkqualityVO>()); //添加审计信息
        bp.addBeforeProcessor(new WorkqualityAddpktantProcessor<WorkqualityVO>()); //添加租户
        bp.addBeforeProcessor(new WorkqualityMultiInsertCheckProcessor(mapper));  //校验检查标准名字唯一性
        bpDetail.addBeforeProcessor(new AuditInfoInsertMultiProcessor<WorkqualityDetailVO>()); //添加审计信息

        // 设置启用状态
        for (WorkqualityVO vo : workqualityVOS) {
            vo.setEnableStatus(EnableStatusConst.ENABLE);
        }

        bp.insert(workqualityVOS);  //批量插入检查标准
        List<WorkqualityDetailVO> detailVOS = new ArrayList<>();
        for(WorkqualityVO vo : workqualityVOS){
            if(vo != null){
                resultList.add(vo.getPkWorkquality());  //更新结果集（插入的检查标准主键）
                if (vo.getItemtabledata() != null){
                    for(WorkqualityDetailVO detailVO : vo.getItemtabledata()){
                        if(detailVO != null){
                            detailVO.setPkWorkquality(vo.getPkWorkquality());  //设置检查项中的检查标准主键
                            detailVO.setEnableStatus(EnableStatusConst.ENABLE);
                            detailVOS.add(detailVO);
                        }
                    }
                }
            }
        }
        bpDetail.insert(detailVOS.toArray(new WorkqualityDetailVO[0])); //批量插入检查项
        return resultList.toArray(new String[0]);
    }

    @Override
    public String updateCopyWorkQuality(String tenantId, int srcCheckType, int toCheckType) throws BusinessException {
        List<WorkqualityVO> workqualityVOList = queryService.queryByChecktypes(tenantId, srcCheckType);
        StringBuilder stringBuilder = new StringBuilder();
        for(WorkqualityVO workqualityVO : workqualityVOList) {
            stringBuilder.append(",'").append(workqualityVO.getPkWorkquality()).append("'");
        }
        String ret = stringBuilder.toString();
        ret = ret.substring(1);
        List<WorkqualityDetailVO> detailVOS = detailMapper.queryByWorkqualityIds(ret);
        Map<String, List<WorkqualityDetailVO>> detailsMap = new HashMap<>();
        for(WorkqualityDetailVO detailVO : detailVOS){
            List<WorkqualityDetailVO> detailVOList = detailsMap.get(detailVO.getPkWorkquality());
            if(detailVOList != null){
                detailVOList.add(detailVO);
            }else {
                detailVOList = new ArrayList<>();
                detailVOList.add(detailVO);
                detailsMap.put(detailVO.getPkWorkquality(), detailVOList);
            }
        }

        SingleInsertBpTemplate<WorkqualityVO> qualityInsertBp = new SingleInsertBpTemplate<>(mapper);
        SingleInsertBpTemplate<WorkqualityDetailVO> detailInsertBp = new SingleInsertBpTemplate<>(detailMapper);
        for(WorkqualityVO workqualityVO : workqualityVOList){
            List<WorkqualityDetailVO> workqualityDetailVOS = detailsMap.get(workqualityVO.getPkWorkquality());
            WorkqualityVO newQualityVo = new WorkqualityVO();
            newQualityVo.setPkTenant(workqualityVO.getPkTenant());
            newQualityVo.setCheckname(workqualityVO.getCheckname());
            newQualityVo.setChecktype(String.valueOf(toCheckType));
            newQualityVo.setCreationtime(Calendar.getInstance().getTime());
            newQualityVo.setCreator("copyFromType[" + srcCheckType + "]");
            newQualityVo.setPkProcedure(workqualityVO.getPkProcedure());
            newQualityVo.setEnableStatus(workqualityVO.getEnableStatus());

            newQualityVo = qualityInsertBp.insert(newQualityVo);

            for(WorkqualityDetailVO detailVO : workqualityDetailVOS){
                WorkqualityDetailVO newDetailVO = new WorkqualityDetailVO();
                newDetailVO.setCreator("copyFromType[" + srcCheckType + "]");
                newDetailVO.setCreationtime(Calendar.getInstance().getTime());
                newDetailVO.setCheckcode(detailVO.getCheckcode());
                newDetailVO.setCheckdescription(detailVO.getCheckdescription());
                newDetailVO.setCheckitem(detailVO.getCheckitem());
                newDetailVO.setPkWorkquality(newQualityVo.getPkWorkquality());
                newDetailVO.setNeedmeasurement(detailVO.getNeedmeasurement());
                newDetailVO.setNeedphoto(detailVO.getNeedphoto());
                newDetailVO.setEnableStatus(detailVO.getEnableStatus());
                detailInsertBp.insert(newDetailVO);
            }

        }
        return "success";
    }
}
